﻿//-----------------------------------------------------------------------
// <copyright file="Open.cs" company="FCIS">
//     Company copyright tag.
// </copyright>
//-----------------------------------------------------------------------

namespace LastVersionOfIpPackage.Operations
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Text;

    /// <summary>
    /// the class has functions of open image by Multi ways
    /// </summary>
    public class Open
    {
        /// <summary>
        /// static object of this class to use this without create object
        /// </summary>
        private static Open open = new Open();

        /// <summary>
        /// Gets or sets the open1.
        /// </summary>
        /// <value>
        /// The open1.
        /// </value>
        public static Open Open1
        {
            get { return Open.open; }
            set { Open.open = value; }
        }

        /// <summary>
        /// Open the image for any type.
        /// </summary>
        /// <param name="path">The path of image.</param>
        /// <returns>
        /// the bitmap of image
        /// </returns>
        public Bitmap OpenImage(string path)
        {
            string[] fileFormat = path.Split('.');
            if (fileFormat[1] == "PPM" || fileFormat[1] == "ppm")
            {
               return this.OpenPPMI(path);
            }
            else
            {
                return this.OpenImageC(path);
            }
        }

        /// <summary>
        /// Open the image for common types.
        /// </summary>
        /// <param name="path">The path of image would open.</param>
        /// <returns>bitmap of image</returns>
        private Bitmap OpenImageC(string path)
        {
            try
            {
               Bitmap image = new Bitmap(path);
                return image;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }

        /// <summary>
        /// Open the PPM image of type p3 or p6.
        /// </summary>
        /// <param name="path">The path of image.</param>
        /// <returns>bitmap of image</returns>
        private Bitmap OpenPPMI(string path)
        {
            FileStream img = new FileStream(path, FileMode.Open);
            StreamReader readImg = new StreamReader(img);
            try
            {
                string s = readImg.ReadLine();
                string commentOrN = readImg.ReadLine();
                if (commentOrN[0] == '#')
                {
                    commentOrN = readImg.ReadLine();
                }

                string[] weidthAndHeigth;
                weidthAndHeigth = commentOrN.Split(' ');
                int weidth = int.Parse(weidthAndHeigth[0]);
                int heigth = int.Parse(weidthAndHeigth[1]);
                Bitmap image = new Bitmap(weidth, heigth);
               Color[,] bufferOfImage = new Color[weidth, heigth];
                if (s == "p3" || s == "P3")
                {
                    this.OpenP3Img(readImg, ref bufferOfImage);
                }
                else if (s == "p6" || s == "P6")
                {
                    img.Close();
                    FileStream img2 = new FileStream(path, FileMode.Open);
                    this.OpenP6Img(img2, ref bufferOfImage);
                    img2.Close();
                }

                readImg.Close();
                img.Close();
                return BufferOfImage.Buffer.GetImage(bufferOfImage);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }

        /// <summary>
        /// Opens the p3 image.
        /// </summary>
        /// <param name="readImg">The file reader of image.</param>
        /// <param name="bufferOfImage">The buffer of image.</param>
        private void OpenP3Img(StreamReader readImg, ref Color[,] bufferOfImage)
        {
            char[] seperate = { ' ', '\n' };
            string[] pixels;
            readImg.ReadLine();
            pixels = readImg.ReadToEnd().Split(seperate, StringSplitOptions.RemoveEmptyEntries);
            int len = 0;
            for (int j = 0; j < bufferOfImage.GetLength(1); j++)
            {
                for (int i = 0; i < bufferOfImage.GetLength(0); i++)
                {
                    try
                    {
                        bufferOfImage[i, j] = Color.FromArgb(int.Parse(pixels[len]), int.Parse(pixels[len + 1]), int.Parse(pixels[len + 2]));
                    }
                    catch (Exception ex)
                    {
                        Logger.LogException(ex);
                        throw ex;
                    }

                    len += 3;
                }
            }
        }

        /// <summary>
        /// Opens the p6 img.
        /// </summary>
        /// <param name="readImg">The read img.</param>
        /// <param name="bufferOfImage">The buffer of image.</param>
        private void OpenP6Img(FileStream readImg, ref Color[,] bufferOfImage)
        {
            byte[] pxl = new byte[readImg.Length];
            readImg.Read(pxl, 0, pxl.Length);
            int len = pxl.Length - (bufferOfImage.GetLength(1) * bufferOfImage.GetLength(0) * 3);
            for (int j = 0; j < bufferOfImage.GetLength(1); j++)
            {
                for (int i = 0; i < bufferOfImage.GetLength(0); i++)
                {
                    try
                    {
                        bufferOfImage[i, j] = Color.FromArgb(pxl[len], pxl[len + 1], pxl[len + 2]);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogException(ex);
                        throw ex;
                    }

                    len += 3;
                }
            }
        }
    }
}
